//
// 函数
//

// 定义函数
function atoi(a: string): number {
  return parseInt(a);
}
// 赋值给变量的匿名函数
const atol: (a: string) => number = function (a: string) {
  return parseFloat(a);
};
// 赋值给变量的匿名箭头函数
const itoa: (i: number) => string = (i: number): string => {
  return i.toString();
};
// 赋值给变量的匿名箭头函数缩写
const ltoa: (l: number) => string = (l: number): string => l.toString();
// 设置参数的默认值
function sum(a: number, b = 10): number {
  return a + b;
}
// 赋值给变量的匿名箭头函数缩写
const say: (...rest: (number | string)[]) => void = (...rest: (number | string)[]): void => console.log(...rest);
// 赋值给变量的匿名箭头函数缩写，返回值和赋值的变量进行了类型推论
const say2 = (...rest: (number | string)[]) => console.log(...rest);
// JS 中的写法，也是合法的 TS
const say3 = (...rest) => console.log(...rest);

//
// 泛型
//
function type<T>(v: T): T {
  console.log("type", v, "to", typeof v);
  return v;
}
const type2: <T>(v: T) => T = type;

//
// 重载
//
function toa(v: string): string;
function toa(v: number): string;
function toa(v: number[]): string;
function toa<T extends object>(v: T): string {
  if ("string" === typeof v) {
    return v;
  }

  if (Array.isArray(v)) {
    return v.join(" ");
  }

  return v.toString();
}

(function main(): void {
  const i: number = atoi("100");
  const a: string = itoa(i);
  say(typeof i, ":", i);
  say(typeof a, ":", a);

  const f: number = atol("100.001");
  const l: string = ltoa(f);
  say2(typeof f, ":", f);
  say2(typeof l, ":", l);

  say3(say, say2, say3);
  say(sum(1, 2), sum(5));

  const t1: string = type<string>("hello");
  const t2: number = type2(1);
  say(typeof t1, ":", t1);
  say(typeof t2, ":", t2);

  say(toa("text"));
  say(toa(1));
  say(toa([1, 2, 3]));
  // No overload matches this call, wrong argument type object
  //say(toa({ a: 1, b: 2 }));
})();

export {};
